package org.easyspring.util;

import lombok.AllArgsConstructor;
import lombok.Data;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @description:
 * @author：hy
 * @date: 2024/9/24
 */
public class Main {
    private static final String SUCCESS_MSG = "成功";
    private static final String ERROR_MSG = "校验失败";
    private static List<Human> humanDb = new ArrayList<>();

    static {
        humanDb.add(new Human(1L,"赵云", "子龙", "男"));
        humanDb.add(new Human(2L,"关羽", "云长", "男"));
        humanDb.add(new Human(3L,"曹操", "孟德", "男"));
    }

    public static void main(String[] args) {
        List<Human> humans = new ArrayList<>();
        humans.add(new Human(1L,"赵云", "子龙", "男", "长坂坡"));
        humans.add(new Human(null,"诸葛亮", "孔明", "男"));
        humans.add(new Human(null,"周瑜", "公瑾", "男"));
        Main main = new Main();
        main.unique(humans);
        System.out.println(SUCCESS_MSG);
        humans.add(new Human(null,"赵云", "子龙", "男"));
        try {
            main.unique(humans);
        } catch (Exception e) {
            System.out.println("catch 1");
            System.out.println(e.getMessage());
        }
        humans.remove(humans.size() - 1);
        humans.add(new Human(2L,"曹操", "孟德", "男"));
        try {
            main.unique(humans);
        } catch (Exception e) {
            System.out.println("catch 2");
            System.out.println(e.getMessage());
        }
    }

    public void unique(List<Human> humans) {
        if (CollectionUtils.isEmpty(humans)) {
            throw new RuntimeException(ERROR_MSG);
        }
        // 查询列表本身是否含有重复数据
        Map<String, List<Human>> humanMap = humans.stream().collect(Collectors.groupingBy(this::getGroupKey));
        humanMap.forEach((k, v) -> {
            if (CollectionUtils.isNotEmpty(v) && v.size() > 1) {
                throw new RuntimeException(ERROR_MSG);
            }
        });
        List<Long> modifyIds = humans.stream().map(Human::getId)
                .filter(Objects::nonNull).collect(Collectors.toList());
        // 获取数据库所有重复数据
        List<Long> dbIds = this.selectRepeatId(humans);
        // 如果是新增重复，modifyIds 必不包含于 dbIds
        // 如果是修改重复，分以下两种情况
        // 1.修改操作均为修改自身非校验字段，modifyIds 必包含于 dbIds
        // 2.修改操作不均为修改自身非校验字段，modifyIds 必不包含于 dbIds
        if (!modifyIds.containsAll(dbIds)) {
            throw new RuntimeException(ERROR_MSG);
        }
    }

    private List<Long> selectRepeatId(List<Human> humans) {
        List<String> keys = humans.stream().map(this::getGroupKey).collect(Collectors.toList());
        return humanDb.stream()
                .filter(v -> keys.contains(this.getGroupKey(v)))
                .map(Human::getId).collect(Collectors.toList());
    }

    private String getGroupKey(Human human) {
        return StringUtils.join(human.getName(), human.getWord(), human.getSex());
    }

    @AllArgsConstructor
    @Data
    static class Human {
        private Long id;
        private String name;
        private String word;
        private String sex;
        private String other;

        public Human(Long id, String name, String word, String sex) {
            this.id = id;
            this.name = name;
            this.word = word;
            this.sex = sex;
        }
    }
}
